package com.fuhe.chen.vendingmachine.controller;

import com.fuhe.chen.vendingmachine.anno.AddLog;
import com.fuhe.chen.vendingmachine.dto.ApiResponse;
import com.fuhe.chen.vendingmachine.common.LoginAPIResponse;
import com.fuhe.chen.vendingmachine.common.Utils;
import com.fuhe.chen.vendingmachine.constant.MessageConstant;
import com.fuhe.chen.vendingmachine.constant.WebConst;
import com.fuhe.chen.vendingmachine.pojo.User;
import com.fuhe.chen.vendingmachine.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.UUID;

import static com.fuhe.chen.vendingmachine.controller.admin.UserController.ROLE_USER;

/**
 * 登录页面控制器
 */
@Controller
@Api(tags = "登录注册接口")
public class LoginController {

    @Autowired
    private IUserService userService;

    /**
     * 前往登录页面
     * @return
     */
    @ApiOperation("前往登录页面")
    @GetMapping("/login")
    public String login(){
        return "admin/login";
    }

    /**
     * 跳转到没有权限页面
     * @return
     */
    @ApiOperation("跳转到没有权限页面")
    @GetMapping("/noAuth")
    public String noAuth(){
        return "noAuth";
    }


    /**
     * 登录动作
     * @param username
     * @param password
     * @param model
     * @param request
     * @return
     */
    @AddLog(operation = "请求登录")
    @ApiOperation("进行登录")
    @PostMapping("/signIn")
    @ResponseBody
    public LoginAPIResponse signIn(
            @RequestParam("username") String username,
            @RequestParam("password")  String password,
            Model model,
            HttpServletRequest request){
        Subject subject = SecurityUtils.getSubject();
        if(Utils.isBlank(password)){
            return LoginAPIResponse.fail(MessageConstant.Error.USERNAME_PASSWORD_IS_EMPTY);
        }
        password = Utils.MD5encode(username+password);
        UsernamePasswordToken token = new UsernamePasswordToken(username,password,false);
        try{
            subject.login(token);
            User userInfo = userService.findOne(username);
            request.getSession().setAttribute(WebConst.LOGIN_SESSION_KEY, userInfo);
        }catch (UnknownAccountException e){
            return LoginAPIResponse.fail("用户名不存在");
        }catch (IncorrectCredentialsException e){
            return LoginAPIResponse.fail("密码错误");
        }

        return LoginAPIResponse.success();
    }

    /**
     * 避免重复登录
     * @param model
     * @return
     */
    @ApiOperation("避免重复登录")
    @GetMapping("/signIn")
    public String signIn(Model model){
        Subject subject = SecurityUtils.getSubject();
        if(subject.isAuthenticated()){
            return "admin/index";
        }
        return "admin/login";
    }

    /**
     * 登出动作
     * @param session
     * @return
     */
    @ApiOperation("登出动作")
    @ResponseBody
    @GetMapping("/logout")
    public LoginAPIResponse logout(HttpSession session){
        Subject subject = SecurityUtils.getSubject();
        if(subject.isAuthenticated()){
            session.removeAttribute(WebConst.LOGIN_SESSION_KEY);
            subject.logout();
        }
        return LoginAPIResponse.success("登出成功");
    }

    /**
     * 注册账户
     * @return
     */
    @AddLog(operation = "注册账户")
    @ApiOperation("注册账户")
    @ResponseBody
    @PostMapping("/signUp")
    public ApiResponse<String> signUp(@RequestParam("username") String username,
                                      @RequestParam("password")  String password,
                                      @RequestParam(name = "phone",required = false) String phone,
                         HttpServletRequest request){
        //TODO:非空检测

        Boolean result = userService.userCheck(username);
        ApiResponse<String> response = new ApiResponse<>();
        if(result){
            response.setSuccess(false);
            response.setMessage(MessageConstant.Error.USERNAME_ALREADY_EXISTS_MESSAGE);
            response.setCode(MessageConstant.Error.USERNAME_ALREADY_EXISTS_CODE);
        }else{
            User newUser = new User();
            String M5Password=Utils.MD5encode(username+password);
            newUser.setId(createUserID());
            newUser.setName(username);
            newUser.setNickname(username);
            newUser.setPassword(M5Password);
            newUser.setPhone(phone);
            newUser.setRole(ROLE_USER);
            newUser.setRegisterDate(System.currentTimeMillis());
            userService.addUser(newUser);

            UsernamePasswordToken token = new UsernamePasswordToken(username,M5Password,false);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            request.getSession().setAttribute(WebConst.LOGIN_SESSION_KEY, newUser);

            response.setSuccess(true);
            response.setMessage(MessageConstant.Success.SIGN_UP_SUCCESS_MESSAGE);
            response.setCode(MessageConstant.Success.SUCCESS_CODE);
        }

        return response;
    }

    //通过uuid生成随机id
    private String createUserID() {
        return  UUID.randomUUID().toString().replace("-", "");
    }

}
